package cn.tedu.csmall520.stock.webapi.controller;

import cn.tedu.csmall520.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall520.commons.restful.JsonResult;
import cn.tedu.csmall520.commons.restful.ResponseCode;
import cn.tedu.csmall520.stock.service.IStockService;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/base/stock")
@Api(tags = "商品库存管理模块")
public class StockController {

    @Autowired
    private IStockService stockService;



    @PostMapping("/reduce/count")
    @ApiOperation("减少库存管理")
//    在方法上添加SentinelResource该注解，运行一次后，会被sentinel仪表台检测到
//    如果该方法不运行，则仪表台中不会显示该方法
    @SentinelResource(value = "减少库存",
            //    blockHandler是注解中的属性，可以指定请求触发限流时，自定义的方法就会被调用运行
            blockHandler = "blockError",
            //    fallback属性，可以指定方法运行发生异常时，运行指定的方法，优先级高于统一异常处理类
            fallback = "fallbackError")
    public JsonResult update (StockReduceCountDTO stockReduceCountDTO) {
        stockService.reduceCount(stockReduceCountDTO);
        return JsonResult.ok("库存减少成功");
    }

//    sentinel自定义限流方法声明
//    规定：1.访问修饰符必须是public
//         2.返回值类型必须和控制器一致
//         3.方法名必须和注解中声明的一致
//         4.方法的参数和控制器一致，然后再额外一个属性，可以指定请求触发限流时表示限流异常
    public JsonResult blockError (StockReduceCountDTO stockReduceCountDTO,
                                  BlockException e){
        //此方法表示方法运行时，遇到被限流，导致走到该方法
        return JsonResult.failed(ResponseCode.UNAUTHORIZED,"服务器忙，请稍后尝试");
    }

    //自定义降级方法定义规则和限流方法一致
    //参数中额外的返回值为Throwable
    //当控制器方法运行异常时，会运行此方法，异常被Throwable接受
    //实际开发过程中可以运行之前版本的代码，所以叫”降级“
    public JsonResult fallbackError (StockReduceCountDTO stockReduceCountDTO,Throwable throwable){
        //输出异常信息到控制台
        throwable.printStackTrace();;
        return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,"方法异常，降级处理");
    }


}
